#include <iostream>
#include <string>

// 雷锋类
class LeiFeng {
    public:
    virtual void Sweep() {
        std::cout << " 扫地" << std::endl;
    }
    virtual void Wash() {
        std::cout << " 洗衣服" << std::endl;

    }
        virtual void BuyRice() {
        std::cout << " 买大米" << std::endl;
    }

};

// 继承雷锋的大学生类
class Undergraduate : public LeiFeng {
    public:
    Undergraduate():name_("无名大学生") {}
    Undergraduate(std::string name):name_(name) {}
    virtual void Sweep() {
        std::cout << "大学生 " << name_;
        LeiFeng::Sweep();
    }
    virtual void Wash() {
        std::cout << "大学生 " << name_;
        LeiFeng::Wash();
    }
    virtual void BuyRice() {
        std::cout << "大学生 " << name_;
        LeiFeng::BuyRice();
    }

    private:
    std::string name_;

};

// 继承雷锋的社区志愿者类
class Volunteer : public LeiFeng {
    public:
    Volunteer():name_("无名志愿者"){}
    Volunteer(std::string name):name_(name){}
    virtual void Sweep() {
        std::cout << "社区志愿者 " << name_;
        LeiFeng::Sweep();
    }
    virtual void Wash() {
        std::cout << "社区志愿者 " << name_;
        LeiFeng::Wash();
    }
    virtual void BuyRice() {
        std::cout << "社区志愿者 " << name_;
        LeiFeng::BuyRice();
    }

    private:
    std::string name_;

};

// 雷锋工厂类，抽象类，不能实例化对象
class IFactory {
    public:
    virtual LeiFeng* CreatLeiFeng(std::string name) = 0;
};

// 学雷锋的大学生工厂类
class UndergraduateFactory : public IFactory {
    public:
    virtual LeiFeng* CreatLeiFeng(std::string name) {
        return new Undergraduate(name);
    }
};

// 学雷锋的志愿者工厂类
class VolunteerFactory : public IFactory {
    public:
    virtual LeiFeng* CreatLeiFeng(std::string name) {
        return new Volunteer(name);
    }
};


int main() {
    std::cout << "hello,factory_method_pattern!!!" << std::endl;
    IFactory* IF1 = new UndergraduateFactory();
    IFactory* IF2 = new VolunteerFactory();
    LeiFeng* student1 = IF1->CreatLeiFeng("大学生A");
    LeiFeng* volunteer1 = IF2->CreatLeiFeng("志愿者B");
    student1->Wash();
    volunteer1->Sweep();
    delete IF1,IF2;
    IF1 = nullptr;
    IF2 = nullptr;
    delete student1,volunteer1;
    student1 = nullptr;
    volunteer1 = nullptr;
    return 0;
}